import {
	IParam,
	IGridControllerParams,
	IContext,
	IOpenViewResult,
	ICtrlActionResult,
	IEvent,
	IGridModel,
	IHttpResponse,
} from '@/core/interface';
import { IGridAbility } from '@/core/interface/widgets/ability';
import { IGridController } from '@/core/interface/widgets/controller';
import { GridActionType } from '@/core/interface/widgets/event';
import { IGridStore } from '@/core/interface/widgets/store';
import { ControlVOBase } from '@/core/modules';
import GridService from '@/core/modules/ctrl-service/grid-service';
import {
	AuthUtil,
	DataTypeUtil,
	dateFormat,
	deepCopy,
	VerifyUtil,
} from '@/core/utils';
import { FormatController } from '@/core/utils/format';
import { MDCtrlController } from './md-ctrl-controller';

/**
 * 表格控制器（todo：方法属性需要加修饰符/能力不完整）
 *
 * @export
 * @class GridController
 * @extends {(MDCtrlController<A | GridEventActionType, IGridStore>)}
 * @implements {IGridController<T>}
 * @template A
 */
export class GridController
	extends MDCtrlController<GridActionType, IGridStore, IGridAbility>
	implements IGridController<IGridStore, IGridAbility>
{
	/**
	 * 表格模型
	 *
	 * @protected
	 * @type {IGridModel}
	 * @memberof GridController
	 */
	protected declare model: IGridModel;

	/**
	 * 表格部件服务
	 *
	 * @protected
	 * @type {GridService<ControlVOBase>}
	 * @memberof GridController
	 */
	protected declare ctrlService: GridService<ControlVOBase>;

	/**
	 * 行激活模式 (0: 无激活、1: 单击激活、2: 双击激活)
	 *
	 * @protected
	 * @type {(0 | 1 | 2)}
	 * @memberof GridController
	 */
	protected rowActiveMode!: 0 | 1 | 2;

	/**
	 * 备份值规则模型
	 *
	 * @private
	 * @type {IParam}
	 * @memberof GridController
	 */
	private backRuleModel: IParam = {};

	/**
	 * 错误信息
	 *
	 * @private
	 * @type {string[]}
	 * @memberof GridController
	 */
	private errorMessages: string[] = [];

	/**
	 * 行为模型
	 *
	 * @private
	 * @type {IParam}
	 * @memberof GridController
	 */
	private actionModel: IParam = {};

	/**
	 * Creates an instance of GridController.
	 * @param {IGridControllerParams} params
	 * @memberof GridController
	 */
	public constructor(
		params: IGridControllerParams<GridActionType, IGridAbility>
	) {
		super(params);
		this.rowActiveMode = params.rowActiveMode;
		this.ctrlInit(params);
	}

	/**
	 * 处理部件初始化
	 *
	 * @protected
	 * @param {IGridControllerParams<GridActionType, IGridAbility>} params
	 * @memberof GridController
	 */
	protected processCtrlInit(
		params: IGridControllerParams<GridActionType, IGridAbility>
	) {
		super.processCtrlInit(params);
		Object.assign(this.store, {
			enableRowEdit: params.defaultEnableRowEdit === true,
			aggData: {},
		});
		this.initRules();
		this.initActionModel();
	}

	/**
	 * 初始化值规则
	 *
	 * @private
	 * @return {*}
	 * @memberof GridController
	 */
	private initRules() {
		if (!this.model.rules) {
			Object.assign(this.store, { rules: {} });
			return;
		}
		const rules: IParam = {};
		const ruleModel: IParam = {};
		const { staticRules, editRules } = this.model.rules;
		if (editRules && editRules.length > 0) {
			editRules.forEach((item: IParam) => {
				ruleModel[item.name] = { error: '' };
				const editorRules = item.editor
					? VerifyUtil.buildVerConditions(item.editor)
					: [];
				const otherRules = staticRules[item.name] || [];
				rules[item.name] = [
					//  非空值规则
					{
						validator(rule: any, value: any, callback: Function) {
							const result =
								!item.allowEmpty &&
								(value === null || value === undefined || value === '')
									? false
									: true;
							if (result) {
								return Promise.resolve();
							}
							return Promise.reject();
						},
						message: `${item.caption || item.name} 必须填写`,
						trigger: ['change', 'blur'],
					},
					...otherRules,
					...editorRules,
				];
			});
		}
		this.backRuleModel = ruleModel;
		Object.assign(this.store, { rules, ruleModel });
	}

	/**
	 * 初始化行为模型
	 *
	 * @private
	 * @return {*}
	 * @memberof GridController
	 */
	private initActionModel() {
		const columns = this.model.columns;
		if (!columns || columns.length === 0) {
			return;
		}
		const actionModel: IParam = {};
		columns.forEach((column: IParam) => {
			if (
				column.columnType === 'UAGRIDCOLUMN' &&
				column.uIActionDetails &&
				column.uIActionDetails.length > 0
			) {
				column.uIActionDetails.forEach((detail: IParam) => {
					Object.assign(actionModel, {
						[detail.uIActionTag]: {
							uIActionTag: detail.uIActionTag,
							disabled: detail.disabled,
							noPrivDisplayMode: detail.noPrivDisplayMode,
							visible: detail.visible,
							dataAccessAction: detail.dataAccessAction,
						},
					});
				});
			}
		});
		this.actionModel = actionModel;
	}

	/**
	 * 处理加载数据变更
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof GridController
	 */
	protected handleLoadDataChange(data: IParam[]): void {
		this.store.data = data;
		const ruleModel = {};
		this.store.data.forEach((item: IParam, index: number) => {
			Object.assign(ruleModel, { [index]: deepCopy(this.backRuleModel) });
			Object.assign(item, this.computeItemAuthState(item));
		});
		this.store.ruleModel = ruleModel;
		if (this.model.aggMode !== 'NONE') {
			this.handleDataAgg();
		}
		this.handleGroup();
		this.handleDefaultSelect();
	}

	/**
	 * 表格数据聚合
	 *
	 * @private
	 * @return {*}
	 * @memberof GridController
	 */
	private handleDataAgg() {
		const { aggMode, columns } = this.model;
		//	聚合数据
		const aggData: IParam = {};
		//	值格式化工具
		const formatUtil = FormatController.getInstance();
		//	当前页聚合
		if (aggMode === 'PAGE') {
			columns.forEach((column: IParam) => {
				const {
					aggMode: cAggMode,
					aggField,
					dataItemName,
					aggValueFormat,
				} = column;
				if (cAggMode === 'NONE') {
					return;
				}
				const values = this.store.data.map((data: IParam) => {
					return data[aggField];
				});
				//	合计
				if (cAggMode === 'SUM') {
					const aggValue = values.reduce((prev: any, curr: any) => {
						const value = Number(curr);
						if (!isNaN(value)) {
							return prev + curr;
						} else {
							return prev;
						}
					}, 0);
					aggData[dataItemName] = aggValueFormat
						? formatUtil.format(aggValue, aggValueFormat)
						: `合计: ${aggValue}`;
					return;
				}
				//	平均值
				if (cAggMode === 'AVG') {
					const aggValue =
						values.reduce((prev: any, curr: any) => {
							const value = Number(curr);
							if (!isNaN(value)) {
								return prev + curr;
							} else {
								return prev;
							}
						}, 0) / values.length;
					aggData[dataItemName] = aggValueFormat
						? formatUtil.format(aggValue, aggValueFormat)
						: `平均值: ${aggValue}`;
					return;
				}
				//	最大值
				if (cAggMode === 'MAX') {
					let maxValue: number | null = null;
					values.forEach((v: any) => {
						const value = Number(v);
						if (!isNaN(value)) {
							if (maxValue === null || value > maxValue) {
								maxValue = value;
							}
						}
					});
					aggData[dataItemName] = aggValueFormat
						? formatUtil.format(maxValue, aggValueFormat)
						: `最大值: ${maxValue}`;
					return;
				}
				//	最小值
				if (cAggMode === 'MIN') {
					let minValue: number | null = null;
					values.forEach((v: any) => {
						const value = Number(v);
						if (!isNaN(value)) {
							if (minValue === null || value < minValue) {
								minValue = value;
							}
						}
					});
					aggData[dataItemName] = aggValueFormat
						? formatUtil.format(minValue, aggValueFormat)
						: `最小值: ${minValue}`;
					return;
				}
			});
			this.store.aggData = aggData;
			console.log(111, this.store);
			return;
		}
		//	全部数据聚合
		if (aggMode === 'ALL') {
			const { aggDeCodeName, aggDataSet } = this.model;
			if (!aggDeCodeName || !aggDataSet) {
				App.getNotificationHelper().warning('', '未配置聚合实体或聚合行为');
				return;
			}
			App.getDataService(aggDeCodeName, this.store.context).then(
				(service: any) => {
					if (
						service &&
						service[aggDataSet] &&
						service[aggDataSet] instanceof Function
					) {
						service[aggDataSet](this.store.context, this.store.viewParams).then(
							(response: IHttpResponse) => {
								if (response.success && response.data) {
									columns.forEach((column: IParam) => {
										const {
											aggMode: cAggMode,
											aggField,
											dataItemName,
											aggValueFormat,
										} = column;
										if (cAggMode === 'NONE') {
											return;
										}
										const aggValue = Number(response.data[aggField]);
										if (isNaN(aggValue)) {
											return;
										}
										//	合计
										if (cAggMode === 'SUM') {
											aggData[dataItemName] = aggValueFormat
												? formatUtil.format(aggValue, aggValueFormat)
												: `合计: ${aggValue}`;
											return;
										}
										//	平均值
										if (cAggMode === 'AVG') {
											aggData[dataItemName] = aggValueFormat
												? formatUtil.format(aggValue, aggValueFormat)
												: `平均值: ${aggValue}`;
											return;
										}
										//	最大值
										if (cAggMode === 'MAX') {
											aggData[dataItemName] = aggValueFormat
												? formatUtil.format(aggValue, aggValueFormat)
												: `最大值: ${aggValue}`;
											return;
										}
										//	最小值
										if (cAggMode === 'MIN') {
											aggData[dataItemName] = aggValueFormat
												? formatUtil.format(aggValue, aggValueFormat)
												: `最小值: ${aggValue}`;
											return;
										}
									});
									this.store.aggData = aggData;
								}
							}
						);
					}
				}
			);
		}
	}

	/**
	 * 计算项权限状态
	 *
	 * @private
	 * @param {IParam} data
	 * @return {*}
	 * @memberof GridController
	 */
	private computeItemAuthState(data: IParam) {
		if (!this.actionModel || Object.keys(this.actionModel).length === 0) {
			return;
		}
		const tempActionModel = deepCopy(this.actionModel);
		if (this.uiService) {
			AuthUtil.calcActionItemAuthState(
				data.getDo(),
				tempActionModel,
				this.uiService
			);
		}
		return tempActionModel;
	}

	/**
	 * 新建默认值
	 *
	 * @param {IParam} data
	 * @memberof GridController
	 */
	public createDefault(data: IParam) {
		const { viewParams, context } = this.store;
		const { createDefaultItems } = this.model;
		if (createDefaultItems.length === 0) {
			return;
		}
		createDefaultItems.forEach((item: IParam) => {
			const { createDVT, createDV, property, valueFormat, dataType } = item;
			if (createDVT && data.hasOwnProperty(property)) {
				switch (createDVT) {
					case 'CONTEXT':
						if (createDV) {
							data[property] = viewParams[createDV];
						}
						break;
					case 'SESSION':
					case 'APPDATA':
						if (createDV) {
							data[property] = context[createDV];
						}
						break;
					case 'OPERATORNAME':
						data[property] = context['srfusername'];
						break;
					case 'OPERATOR':
						data[property] = context['srfuserid'];
						break;
					case 'CURTIME':
						data[property] = valueFormat
							? dateFormat(new Date(), valueFormat)
							: new Date().toDateString();
						break;
					case 'PARAM':
						if (item.createDV) {
							data[property] = this.computeDefaultValueWithParam(
								'CREATE',
								item.createDV,
								data
							);
						}
						break;
				}
			} else if (createDV && data.hasOwnProperty(property)) {
				data[property] =
					dataType && DataTypeUtil.isNumber(dataType)
						? Number(createDV)
						: createDV;
			}
		});
	}

	/**
	 * 更新默认值
	 *
	 * @param {IParam} row
	 * @memberof GridController
	 */
	public updateDefault(row: IParam) {
		const { viewParams, context, data } = this.store;
		const { updateDefaultItems } = this.model;
		if (updateDefaultItems.length === 0 || data.length === 0) {
			return;
		}
		updateDefaultItems.forEach((item: IParam) => {
			const { updateDV, updateDVT, property, valueFormat, dataType } = item;
			if (updateDVT && row.hasOwnProperty(property)) {
				switch (updateDVT) {
					case 'CONTEXT':
						if (updateDV) {
							row[property] = viewParams[updateDV];
						}
						break;
					case 'SESSION':
					case 'APPDATA':
						if (updateDV) {
							row[property] = context[updateDV];
						}
						break;
					case 'OPERATORNAME':
						row[property] = context['srfusername'];
						break;
					case 'OPERATOR':
						row[property] = context['srfuserid'];
						break;
					case 'CURTIME':
						row[property] = valueFormat
							? dateFormat(new Date(), valueFormat)
							: new Date().toDateString();
						break;
					case 'PARAM':
						if (item.createDV) {
							row[property] = this.computeDefaultValueWithParam(
								'UPDATE',
								updateDV,
								row
							);
						}
						break;
				}
			} else if (updateDV && row.hasOwnProperty(property)) {
				row[property] =
					dataType && DataTypeUtil.isNumber(dataType)
						? Number(updateDV)
						: updateDV;
			}
		});
	}

	/**
	 * 计算数据对象类型的默认值
	 * @param {string}  action 行为
	 * @param {string}  param 默认值参数
	 * @param {*}  data 当前行数据
	 * @memberof GridControlBase
	 */
	public computeDefaultValueWithParam(
		action: string,
		param: string,
		data: any
	) {
		if (Object.is(action, 'UPDATE')) {
			const nativeData: IParam[] = this.ctrlService.getCopynativeData();
			if (nativeData && nativeData instanceof Array && nativeData.length > 0) {
				const deCodeName = this.model.entityCodeName.toLowerCase();
				const targetData: IParam | undefined = nativeData.find((item: any) => {
					return item[deCodeName] === data.srfkey;
				});
				if (targetData) {
					return targetData[param] ? targetData[param] : null;
				} else {
					return null;
				}
			} else {
				return null;
			}
		} else {
			return this.ctrlService.getRemoteCopyData()[param]
				? this.ctrlService.getRemoteCopyData()[param]
				: null;
		}
	}

	/**
	 * 处理部件事件
	 *
	 * @param {IEvent<string>} actionParam
	 * @param {number} index
	 * @memberof GridController
	 */
	public handleComponentAction(actionParam: IEvent<string>, index: number) {
		const { name, action, data } = actionParam;
		switch (action) {
			case 'valueChange':
				this.handleItemValueChange(name, data, index);
				break;
		}
	}

	/**
	 * 处理值变更
	 *
	 * @protected
	 * @param {string} name
	 * @param {*} value
	 * @param {number} index
	 * @return {*}
	 * @memberof GridController
	 */
	protected handleItemValueChange(name: string, value: any, index: number) {
		const data = this.store.data[index];
		if (!data || !data.hasOwnProperty(name) || data[name] === value) {
			return;
		}
		this.store.data[index][name] = value;
		//  修改行数据状态
		if (this.store.data[index].srfuf === '0') {
			this.store.data[index].$rowDataState = 'craete';
		} else {
			this.store.data[index].$rowDataState = 'update';
		}
		this.validateItem(name, value, index);
		this.handleItemUpdate(name, value, index);
	}

	/**
	 * 处理表格编辑项更新
	 *
	 * @private
	 * @param {string} name
	 * @param {*} value
	 * @param {number} index
	 * @memberof GridController
	 */
	private handleItemUpdate(name: string, value: any, index: number) {
		const { columns } = this.model;
		const column = columns.find((c: IParam) => c.dataItemName === name);
		if (column && column.itemUpdate) {
			const { details, method, showBusyIndicator, scriptCode } =
				column.itemUpdate;
			//	脚本代码
			if (scriptCode) {
				const context = this.store.context;
				const viewParams = this.store.viewParams;
				const data = this.store.data[index][name];
				eval(scriptCode);
			} else {
				this.updateGridEditItem(
					method,
					this.store.data[index][name],
					details,
					index,
					showBusyIndicator
				);
			}
		}
	}

	/**
	 * 表格编辑项更新
	 *
	 * @param {string} action 更新行为
	 * @param {IParam} data 更新行数据
	 * @param {string[]} updateDetails 更新影响项
	 * @param {number} index 数据下标
	 * @param {boolean} [showInfo] 是否显示处理结果
	 * @return {*}
	 * @memberof GridController
	 */
	public updateGridEditItem(
		action: string,
		data: IParam,
		updateDetails: string[],
		index: number,
		showInfo?: boolean
	) {
		if (!action || action === '') {
			return;
		}
		const tempContext = deepCopy(this.store.context);
		const deCodeName = this.model.entityCodeName.toLowerCase();
		Object.assign(tempContext, {
			[deCodeName]: data[deCodeName] || data.srfkey,
		});
		const arg: IParam = deepCopy(data);
		Object.assign(arg, this.store.viewParams);
		this.beforeAsyncAction('updateGridEditItem', tempContext, arg);
		this.ctrlService
			.frontLogic(action, tempContext, arg)
			.then((response: IHttpResponse) => {
				this.afterAsyncAction('updateGridEditItem', response);
				if (!response.success) {
					if (showInfo) {
						App.getNotificationHelper().error('', '表格编辑项更新失败');
					}
					return;
				}
				const _data: any = response.data;
				if (!_data) {
					return;
				}
				updateDetails.forEach((name: string) => {
					if (!_data.hasOwnProperty(name)) {
						return;
					}
					this.store.data[index][name] = _data[name];
				});
			})
			.catch((error: any) => {
				this.afterAsyncAction('updateGridEditItem', error);
				if (showInfo) {
					App.getNotificationHelper().error('', '表格编辑项更新失败');
				}
			});
	}

	/**
	 * 校验项
	 *
	 * @private
	 * @param {string} name
	 * @param {*} value
	 * @param {number} index
	 * @memberof GridController
	 */
	private validateItem(
		name: string,
		value: any,
		index: number
	): Promise<boolean> {
		const data = this.store.data[index];
		const { ruleModel } = this.store;
		return new Promise((resolve: any) => {
			VerifyUtil.validateItem(name, data, this.store.rules)
				.then((result: any) => {
					ruleModel[index][name] = { error: null };
					resolve(true);
				})
				.catch(({ errors }: any) => {
					if (errors && errors.length > 0) {
						ruleModel[index][name] = { error: errors[0].message };
					} else {
						ruleModel[index][name] = { error: '值规则校验错误' };
					}
					resolve(false);
				});
		});
	}

	/**
	 * 校验
	 *
	 * @private
	 * @param {IParam[]} [items] 需要检验的项（不传入则校验全部数据）
	 * @return {*}  {Promise<boolean>}
	 * @memberof GridController
	 */
	private async validate(items?: IParam[]): Promise<boolean> {
		this.errorMessages = [];
		let validateState = true;
		let index = -1;
		const validateItems = items && items.length > 0 ? items : this.store.data;
		for (const item of validateItems) {
			let tempMessage = '';
			index += 1;
			if (item.$rowDataState === 'create' || item.$rowDataState === 'update') {
				for (const property of Object.keys(this.store.rules)) {
					if (!(await this.validateItem(property, item, index))) {
						validateState = false;
						tempMessage =
							tempMessage +
							'<p>' +
							this.store.ruleModel[index][property].error +
							'</p>';
					}
				}
			}
			if (tempMessage) {
				this.errorMessages.push(tempMessage);
			}
		}
		return validateState;
	}

	/**
	 * 新建行
	 *
	 * @param {*} [opts]
	 * @return {*}  {Promise<IHttpResponse>}
	 * @memberof GridController
	 */
	async newRow(opts: IParam[] = []): Promise<ICtrlActionResult> {
		const { loadDraftAction } = this.actions;
		if (!loadDraftAction) {
			App.getNotificationHelper().warning('错误', '未配置新建行为');
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const { context, viewParams } = this.store;
		const arg =
			opts && opts.length > 0 ? opts[0] : { viewParams: deepCopy(viewParams) };
		const tempContext: IContext = deepCopy(context);
		this.beforeAsyncAction('newRow', tempContext, arg);
		try {
			const response = await this.ctrlService.loadDraft(
				loadDraftAction,
				context,
				arg
			);
			this.afterAsyncAction('newRow', response);
			if (!response.success) {
				return { ok: false, data: this.getData(), rowData: { status: 500 } };
			}
			const data = response.data;
			this.createDefault(data);
			this.store.data.unshift(data);
			this.store.ruleModel[this.store.data.length - 1] = deepCopy(
				this.backRuleModel
			);
			return { ok: true, data: this.getData(), rowData: response };
		} catch (error: any) {
			this.afterAsyncAction('newRow', error);
			return { ok: false, data: this.getData(), rowData: error };
		}
	}

	/**
	 * 保存数据
	 *
	 * @param {IParam} [opts={}]
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof GridController
	 */
	async save(opts: IParam = {}): Promise<ICtrlActionResult> {
		const { viewParams, data, context } = this.store;
		const items: IParam[] = [];
		this.store.data.forEach((item: IParam) => {
			items.push(item.toObject());
		});
		if (
			viewParams &&
			(viewParams.copymode === true || viewParams.copymode === 'true') &&
			data.length > 0
		) {
			items.forEach((item: IParam) => {
				item.$rowDataState = 'create';
			});
		}
		//  更新默认值
		items.forEach((item: IParam) => {
			if (item.$rowDataState === 'update') {
				this.updateDefault(item);
			}
		});
		//  没有新建或更新状态的数据直接返回
		if (
			items.filter(
				(_item: IParam) =>
					_item.$rowDataState === 'create' || _item.$rowDataState === 'update'
			).length === 0
		) {
			return { ok: true, data: this.getData(), rowData: {} };
		}
		if (!(await this.validate(items))) {
			this.showValidateMessage();
			return { ok: true, data: this.getData(), rowData: { status: 500 } };
		}
		const tempViewParams = deepCopy(viewParams);
		const successItems: IParam[] = [];
		const errorItems: IParam[] = [];
		const errorMessage: IParam[] = [];
		const { createAction, updateAction } = this.actions;
		for (const item of items) {
			try {
				if (Object.is(item.$rowDataState, 'create') || item.srfuf === '0') {
					if (!createAction) {
						App.getNotificationHelper().warning('警告', '未配置新建行为');
					} else {
						Object.assign(item, { viewParams: tempViewParams });
						const tempContext = deepCopy(context);
						this.beforeAsyncAction('create', tempContext, item);
						const response = await this.ctrlService.add(
							createAction,
							tempContext,
							item
						);
						this.afterAsyncAction('create', response);
						successItems.push(response.data);
					}
				} else if (Object.is(item.$rowDataState, 'update')) {
					if (!updateAction) {
						App.getNotificationHelper().warning('警告', '未配置更新行为');
					} else {
						Object.assign(item, { viewParams: tempViewParams });
						const tempContext = deepCopy(context);
						const entityCodeName = this.model.entityCodeName.toLowerCase();
						if (entityCodeName) {
							Object.assign(tempContext, {
								[entityCodeName.toLowerCase()]:
									item[entityCodeName.toLowerCase()],
							});
						}
						this.beforeAsyncAction('update', tempContext, item);
						const response = await this.ctrlService.update(
							updateAction,
							tempContext,
							item
						);
						this.afterAsyncAction('update', response);
						successItems.push(response.data);
					}
				}
			} catch (error: any) {
				this.afterAsyncAction('save', error);
				errorItems.push(item);
				errorMessage.push(error);
			}
		}
		this.emit('save', successItems);
		const success: boolean = errorItems.length === 0 && successItems.length > 0;
		if (success) {
			this.refresh();
			if (
				!(
					opts &&
					opts.hasOwnProperty('showResultInfo') &&
					(opts['showResultInfo'] === false ||
						opts['showResultInfo'] === 'false')
				)
			) {
				App.getNotificationHelper().success('', '保存成功');
			}
		} else {
			//  TODO 处理保存错误
			if (
				!(
					opts &&
					opts.hasOwnProperty('showResultInfo') &&
					(opts['showResultInfo'] === false ||
						opts['showResultInfo'] === 'false')
				)
			) {
				App.getNotificationHelper().error('', '保存失败');
			}
		}
		return {
			ok: success,
			data: this.getData(),
			rowData: { status: success ? 200 : 500 },
		};
	}

	/**
	 * 删除数据
	 *
	 * @param {IParam} [datas={}]
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof GridController
	 */
	async remove(datas: IParam[] = []): Promise<ICtrlActionResult> {
		const { removeAction } = this.actions;
		if (!removeAction) {
			App.getNotificationHelper().warning('', '未配置删除行为');
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const deleteItems: IParam[] = [];
		//	已选中数据
		datas.forEach((record: IParam) => {
			if (record.$rowDataState === 'create' || record.srfuf === '0') {
				const index = this.store.data.findIndex(
					(i: IParam) => i.srfkey === record.srfkey
				);
				if (index !== -1) {
					this.store.data.splice(index, 1);
				}
			} else {
				deleteItems.push(record);
			}
		});
		if (deleteItems.length === 0) {
			return { ok: true, data: this.getData(), rowData: { status: 200 } };
		}
		let dataInfo = '';
		deleteItems.forEach((item: IParam, index: number) => {
			if (index < 5) {
				if (dataInfo !== '') {
					dataInfo += '、';
				}
				dataInfo += item.srfmajortext ? item.srfmajortext : '';
			}
		});
		if (!dataInfo) {
			dataInfo = `选中${deleteItems.length}条数据`;
		} else {
			if (deleteItems.length < 5) {
				dataInfo += ` 共${deleteItems.length}条数据`;
			} else {
				dataInfo += `...${deleteItems.length}条数据`;
			}
		}
		//	去除null和undefined
		dataInfo = dataInfo.replace(/[null]/g, '').replace(/[undefined]/g, '');
		const removeData = () => {
			const keys: string[] = [];
			deleteItems.forEach((item: IParam) => keys.push(item.srfkey));
			if (keys.length === 0) {
				return;
			}
			const { context, viewParams } = this.store;
			let _removeAction = removeAction;
			if (Object.is(removeAction, 'RemoveTemp') && keys.length > 1) {
				_removeAction = 'RemoveBatchTemp';
			}
			const tempContext: any = deepCopy(context);
			const _keys: string[] | string = keys.length > 1 ? keys : keys[0];
			const { entityCodeName } = this.model;
			const arg = { [entityCodeName.toLowerCase()]: _keys };
			let promises: Promise<any> | null = null;
			if (keys && keys.length > 1) {
				const promiseArr: any = [];
				(_keys as string[]).forEach((ele: any) => {
					Object.assign(tempContext, { [entityCodeName.toLowerCase()]: ele });
					Object.assign(arg, { viewParams: deepCopy(viewParams) });
					Object.assign(arg, { [entityCodeName.toLowerCase()]: ele });
					promiseArr.push(
						this.ctrlService.delete(_removeAction, tempContext, arg)
					);
				});
				promises = Promise.all(promiseArr);
			} else {
				Object.assign(tempContext, { [entityCodeName.toLowerCase()]: _keys });
				Object.assign(arg, { viewParams: deepCopy(viewParams) });
				promises = this.ctrlService.delete(_removeAction, tempContext, arg);
			}
			this.beforeAsyncAction('remove', tempContext, arg);
			if (promises) {
				promises
					.then(async (response: any) => {
						this.afterAsyncAction('remove', response);
						if (!response.success && !Array.isArray(response)) {
							App.getNotificationHelper().error(
								'',
								`删除数据失败, ${response.info}`
							);
							return;
						} else {
							App.getNotificationHelper().success('', '删除数据成功');
						}
						//删除items中已删除的项
						deleteItems.forEach((data: any) => {
							this.store.data.some((item: any, index: number) => {
								if (Object.is(item.srfkey, data.srfkey)) {
									this.store.data.splice(index, 1);
									delete this.store.ruleModel[index];
									return true;
								}
							});
						});
						this.store.totalRecord -= deleteItems.length;
						this.emit('remove', deleteItems);
						this.store.selections = [];
						this.refresh();
					})
					.catch(async (error: any) => {
						this.afterAsyncAction('remove', error);
					});
			}
		};
		App.getDialogHelper().confirm(
			'警告',
			`确认要删除${dataInfo}, 删除操作将不可恢复?`,
			() => {
				removeData();
			}
		);
		return { ok: true, data: this.getData(), rowData: { status: 200 } };
	}

	/**
	 * 刷新
	 *
	 * @param {(IParam | undefined)} [args]
	 * @return {*}  {Promise<boolean>}
	 * @memberof GridController
	 */
	public async refresh(args?: IParam | undefined): Promise<boolean> {
		try {
			const result = await this.load({ srfpagereset: true });
			if (result.ok) {
				return true;
			}
		} catch (error) {
			return false;
		}
		return false;
	}

	/**
	 * 表格行点击
	 *
	 * @param {IParam} row
	 * @param {MouseEvent} event
	 * @memberof GridController
	 */
	rowClick(row: IParam, event: MouseEvent) {
		const selections = this.store.selections;
		if (this.singleSelect) {
			selections.length = 0;
			selections.push(row);
		} else {
			const index = selections.findIndex(
				(select: IParam) => select.srfkey === row.srfkey
			);
			//	未选中
			if (index === -1) {
				this.store.selections.push(row);
			} else {
				this.store.selections.splice(index, 1);
			}
		}
		this.emit('selectionChange', this.getData());
		if (this.rowActiveMode === 1) {
			this.emit('dataActive', [row]);
		}
	}

	/**
	 * 表格行双击
	 *
	 * @param {IParam} row
	 * @param {MouseEvent} event
	 * @memberof GridController
	 */
	rowDbClick(row: IParam, event: MouseEvent) {
		const selections = this.store.selections;
		if (this.singleSelect) {
			selections.length = 0;
			selections.push(row);
		} else {
			const index = selections.findIndex(
				(select: IParam) => select.srfkey === row.srfkey
			);
			//	未选中
			if (index === -1) {
				this.store.selections.push(row);
			} else {
				this.store.selections.splice(index, 1);
			}
		}
		this.emit('selectionChange', this.getData());
		if (this.rowActiveMode === 2) {
			this.emit('dataActive', [row]);
		}
	}

	/**
	 * 选中数据
	 *
	 * @param {IParam[]} selections
	 * @memberof GridController
	 */
	selectionChange(selections: IParam[]) {
		this.store.selections = selections;
		this.emit('selectionChange', this.getData());
	}

	/**
	 * @description 数据导入
	 * @param {IContext} context
	 * @param {IParam} viewParams
	 * @param {IParam[]} data
	 * @memberof GridController
	 */
	importExcel(context: IContext, viewParams: IParam, data: IParam[]) {
		if (!this.model.dataImport) {
			App.getNotificationHelper().warning('失败', '请配置数据导入项');
			return;
		}
		const view: any = {
			name: 'app-data-import',
			caption: '导入数据',
			codeName: 'AppDataImport',
			width: 550,
			height: 370,
		};
		const { dataImport } = this.model;
		const tempContext = deepCopy(context);
		const tempViewParams = deepCopy(viewParams);
		Object.assign(tempViewParams, {
			importId: dataImport.codeName,
			serviceName: this.model.entityCodeName,
			appDeLogicName: this.model.entityLogicName,
			ignoreError: dataImport.ignoreError,
		});
		if (
			dataImport.importItems &&
			dataImport.importItems.length > 0 &&
			import.meta.env.VITE_MODE === 'R7'
		) {
			Object.assign(tempViewParams, { importItems: dataImport.importItems });
		}
		App.getOpenViewHelper()
			.openModal(view, tempContext, tempViewParams)
			.then((result: IOpenViewResult) => {
				if (result.ok) {
					this.refresh();
				}
			});
	}

	/**
	 * 选择全部
	 *
	 * @memberof GridController
	 */
	public selectAll(): void {
		//  TODO 暂不考虑单选情况
		this.store.selections = this.store.data;
		this.emit('selectionChange', this.getData());
	}

	/**
	 * 选中数据
	 *
	 * @param {IParam[]} items 选中数据
	 * @param {boolean} [reverse] 是否反选
	 * @memberof GridController
	 */
	public selectItems(items: IParam[], reverse?: boolean) {
		//  TODO 暂不考虑单选情况
		const selections: IParam[] = [];
		this.store.data.forEach((item: IParam) => {
			const index = items.findIndex((i: IParam) => i.srfkey === item.srfkey);
			//  反选时未在items中选中，正选时在items中选中
			if ((reverse && index === -1) || (!reverse && index !== -1)) {
				selections.push(item);
			}
		});
		this.store.selections = selections;
		this.emit('selectionChange', this.getData());
	}

	/**
	 * 切换行编辑
	 *
	 * @memberof GridController
	 */
	toggleRowEdit(): void {
		this.store.enableRowEdit = !this.store.enableRowEdit;
	}

	/**
	 * 显示校验信息
	 *
	 * @memberof GridController
	 */
	public showValidateMessage() {
		if (this.errorMessages.length > 0) {
			//  TODO 目前只显示第一行信息，后续考虑优化
			App.getNotificationHelper().error(
				'表格值规则校验错误',
				this.errorMessages[0]
			);
		}
	}

	/**
	 * 获取能力
	 *
	 * @template A
	 * @return {*}  {A}
	 * @memberof GridController
	 */
	getAbility(): IGridAbility {
		return {
			...super.getAbility(),
			importExcel: this.importExcel.bind(this),
			newRow: this.newRow.bind(this),
			toggleRowEdit: this.toggleRowEdit.bind(this),
			save: this.save.bind(this),
			remove: this.remove.bind(this),
			// loadDraft: this.newRow.bind(this)
		};
	}
}
